<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>设计模式</title>
</head>

<body>
  <script>
    // 1.观察者模式
    class Publisher {
      constructor() {
        this.observers = []
        console.log('发布者创建完毕');
      }

      add(observer) {
        // 添加观察者
        this.observers.push(observer)
      }

      remove(observer) {
        // 删除观察者
        let index = this.observers.indexOf(observer)
        if (index > -1) {
          this.observers.splice(index, 1)
        }
      }

      notify() {
        this.observers.forEach((observer) => {
          observer.update(this)
        })
      }
    }

    // 发布订阅模式  EventBus实现
    class EventEmitter {
      constructor() {
        this.handles = {}
      }

      on(eventName, fn) {
        if (!this.handles[eventName]) {
          this.handles[eventName] = []
        }

        this.handles[eventName].push(fn)
      }

      emit(eventName, ...args) {
        let events = this.handles[eventName].slice()
        events.forEach((fn) => {
          fn(...args)
        })
      }

      off(eventName, fn) {
        this.handles[eventName].forEach((cb, i) => {
          if (cb === fn) {
            this.handles[eventName].splice(i, 1)
          }
        })
      }

      once(eventName, fn) {
        const wrapper = (...args) => {
          fn(...args)
          this.off(eventName, fn)
        }

        this.on(eventName, wrapper)
      }
    }
  </script>
</body>

</html>